package com.hippy.erya.config.interceptor;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hippy.erya.base.RequestJson;
import com.hippy.erya.common.Constants;
import com.hippy.erya.common.utils.SecurityCommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonInputMessage;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestControllerAdvice
public class LogRequestAdvice implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {

        //进行map转实体
        ByteArrayInputStream inputStream = null;
        try {
            inputStream = convert(httpInputMessage.getBody(),methodParameter);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return new MappingJacksonInputMessage(inputStream, httpInputMessage.getHeaders());


    }

    private ByteArrayInputStream convert(InputStream body, MethodParameter methodParameter) throws Exception {

        String content = StreamUtils.copyToString(body, StandardCharsets.UTF_8);
        //json转实体类
        RequestJson requestJson = JSON.parseObject(content,RequestJson.class);

        Map<String,Object> minMap=new HashMap<>(16);

        boolean switchFlag=false;

        if(switchFlag){
            String aesKey = Constants.AES_KEY;
            String md5Key = Constants.Md5_KEY;

            if("".equals(aesKey) || "".equals(md5Key))
            {
                throw new IOException("无初始化参数");
            }

            Map<String, Object> signResult = SecurityCommonUtil.decodeMesByPassword(md5Key,aesKey, requestJson.getDataStr());
            String code = (String) signResult.get("code");
            if (!"0000".equals(code)) {
                throw new IOException((String) signResult.get("message"));
            }
            requestJson= JSONObject.parseObject((String) signResult.get("signStr"),RequestJson.class);
        }
        String requestJsonStr = JSONObject.toJSONString(requestJson,
                SerializerFeature.PrettyFormat,
                SerializerFeature.QuoteFieldNames,
                // Enum输出name()或者original，默认为false
                SerializerFeature.WriteEnumUsingToString,
                // 是否输出值为null的字段，默认为false，即不设置即为false
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.DisableCircularReferenceDetect,
                // 字符类型字段如果为null， 输出为""， 而非null
                SerializerFeature.WriteNullStringAsEmpty,
                // List字段如果为null， 输出为[]， 而非null
                SerializerFeature.WriteNullListAsEmpty,
                // Boolean字段如果为null， 输出为false， 而非null
                SerializerFeature.WriteNullBooleanAsFalse,
                // 数值字段如果为null， 输出为0， 而非null
                SerializerFeature.WriteNullNumberAsZero
        );

        // 输出请求报文到日志载体中
        String containingClass = methodParameter.getContainingClass().toString();
        log.info("【" + containingClass.substring(containingClass.lastIndexOf(".") + 1, containingClass.length()) + "." + methodParameter.getMethod().getName() + "----请求报文】：\n" + requestJsonStr);

        return new ByteArrayInputStream(requestJsonStr.getBytes());
    }


    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        if (!(o instanceof RequestJson)) {
            return o;
        }

        // 获取RequestJson对象
        RequestJson requestJson = (RequestJson)o;

        // 加工请求报文
//        String requestJsonStr = reqProcess(requestJson);

        // 加锁



        return requestJson;
    }

    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }


    private void lock(String userId, String tradeCode, String reqId) {

        String key = userId + ":" + tradeCode;
        try {
//            boolean bool = RedisZoomkeeper.lock(key, reqId, 60);

        } catch (Exception e) {

        }
    }


}
